package live.mehiz.mpvkt.preferences.preference

import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow

interface Preference<T> {

  fun key(): String

  fun get(): T

  fun set(value: T)

  fun isSet(): Boolean

  fun delete()

  fun defaultValue(): T

  fun changes(): Flow<T>

  fun stateIn(scope: CoroutineScope): StateFlow<T>
}

inline fun <reified T, R : T> Preference<T>.getAndSet(crossinline block: (T) -> R) = set(
  block(get()),
)

inline fun <reified T> Preference<T>.deleteAndGet(): T {
  delete()
  return get()
}

operator fun <T> Preference<Set<T>>.plusAssign(item: T) {
  set(get() + item)
}

operator fun <T> Preference<Set<T>>.minusAssign(item: T) {
  set(get() - item)
}

fun Preference<Boolean>.toggle(): Boolean {
  set(!get())
  return get()
}

@Composable
fun <T> Preference<T>.collectAsState(): State<T> {
  val flow = remember(this) { changes() }
  return flow.collectAsState(initial = get())
}
